<template>
  <div>
    <a-modal v-model="showCrudModal" title="生成CRUD代码" @ok="doGenCrud">
      <table class="form">
        <tr>
          <td class="label need w120">后端包名</td>
          <td>
            <a-input-group compact>
              <a-input disabled style="width:30%" value="com.lt.java."></a-input>
              <a-input style="width:70%" v-model.trim="packageName"></a-input>
            </a-input-group>
          </td>
        </tr>
        <tr>
          <td class="label need">前端代码位置</td>
          <td><a-input v-model.trim="vueLocation"></a-input></td>
        </tr>
      </table>
    </a-modal>
    <TableEdit ref="tableEdit" @save="addTable"></TableEdit>
    <ColumnEdit ref="columnEdit" @save="saveColumn"></ColumnEdit>
    <OptionEdit ref="optEdit"></OptionEdit>
    <DicCodeSet ref="dicCodeSet"></DicCodeSet>
    <a-row :gutter="10">
      <a-col :span="6">
        <a-card>
          <div slot="title" class="flx-s">
            <a-input v-model.trim="prefix" placeholder="表前缀">
              <div slot="addonAfter" class="cpt" @click="searchTable">查询</div>
            </a-input>
            <a-button class="ml10" @click="toAddTable" :loading="loading">
              <i class="fa fa-plus mr5"/>表
            </a-button>
          </div>
          <div v-if="tableLoading" class="flx-c">
            <a-spin tip="加载数据表..."></a-spin>
          </div>
          <div v-else>
            <div style="background:#f2f2f2;" class="fs12 pt4 pb4 bor-rds-15 tac mb10">共{{ tables.length }}个表</div>
            <div class="flx-b bor-rds-3 pd5 cpt mb10" style="border-bottom:solid 1px #e8e8e8" v-for="table in pageList" :key="`t`+table" :class="{curr:table===currTable}">
              <span @click="change(table)">{{ table }}</span>
              <span @click="delTable(table)"><i class="fa fa-trash"/></span>
            </div>
            <a-row v-show="total>0">
              <a-col span="12">
                <a-button type="" @click="prev">上一页</a-button>
              </a-col>
              <a-col span="12" class="tar">
                <a-button type="" @click="next">下一页</a-button>
              </a-col>
            </a-row>
          </div>
        </a-card>
      </a-col>
      <a-col :span="18">
        <a-card>
          <div class="flx-c h400" v-if="currTable.length===0">
            <a-empty description="请您先选择一张表" />
          </div>
          <div v-else>
            <a-tabs v-model="tab">
              <a-tab-pane :key="1" tab="自定义字段">
                <a-table
                  :customHeaderRow="customHeaderRow"
                  rowKey="id"
                  size="small"
                  bordered
                  :pagination="false"
                  :data-source="otherColumns"
                  :scroll="{ x: scrollX, y: winHeight-300 }">
                  <a-table-column title="字段" dataIndex="columnName" :width="200" fixed="left">
                    <template slot-scope="text,record">
                      <span>{{ record.formLabel }}【{{ record.columnName }}】</span>
                    </template>
                  </a-table-column>
                  <a-table-column title="字段类型" :width="120" fixed="left">
                    <template slot-scope="text,record">
                      <span>{{ record.columnType }}</span>
                      <span v-if="record.columnLength>0">【{{ record.columnLength }}】</span>
                    </template>
                  </a-table-column>
                  <a-table-column v-if="['all','base'].includes(currConfSenceCode)" title="数据类型">
                    <template slot-scope="text,record">
                      <ZgEnum code="数据类型" v-model="record.dataType" @change="handlePropertyChange('dataType',$event,record)"></ZgEnum>
                    </template>
                  </a-table-column>
                  <a-table-column v-if="['all','view'].includes(currConfSenceCode)" title="组件类型" :width="200">
                    <template slot-scope="text,record">
                      <div class="flx-s">
                        <a-select class="w140" v-model="record.compType" @change="handlePropertyChange('compType',$event,record)">
                          <a-select-option v-for="t in findTypes(record)" :key="t.key">
                            {{ t.name }}
                          </a-select-option>
                        </a-select>
                        <div
                          class="btn-circle flx-c ml10"
                          v-show="record.compType==='dic'"
                          @click="toSetDicCode(record)"
                          title="为字段设置字典编码">
                          <i class="fa fa-bars"></i>
                        </div>
                        <div
                          class="btn-circle flx-c ml10"
                          v-show="needOpts(record)"
                          @click="toSetOpts(record)"
                          title="为字段设置选项">
                          <i class="fa fa-bars"></i>
                        </div>
                      </div>
                    </template>
                  </a-table-column>
                  <a-table-column v-if="['all','header'].includes(currConfSenceCode)" title="表头名称" :width="160">
                    <template slot-scope="text,record">
                      <ZgInput @enter="handlePropertyChange('headerName',record.headerName,record)" v-model="record.headerName"></ZgInput>
                    </template>
                  </a-table-column>
                  <a-table-column v-if="['all','header'].includes(currConfSenceCode)" title="表头宽度">
                    <template slot-scope="text,record">
                      <ZgNumber @change="handlePropertyChange('headerWidth',record.headerWidth,record)" v-model="record.headerWidth"></ZgNumber>
                    </template>
                  </a-table-column>
                  <a-table-column v-if="['all','header'].includes(currConfSenceCode)" title="表头显示">
                    <template slot-scope="text,record">
                      <a-switch @change="handlePropertyChange('headerShow',$event,record)" v-model="record.headerShow" checked-children="显示" un-checked-children="不显示"/>
                    </template>
                  </a-table-column>
                  <a-table-column v-if="['all','header'].includes(currConfSenceCode)" title="表头顺序">
                    <template slot-scope="text,record">
                      <ZgNumber @change="handlePropertyChange('headerSort',record.headerSort,record)" v-model="record.headerSort"></ZgNumber>
                    </template>
                  </a-table-column>
                  <a-table-column v-if="['all','base'].includes(currConfSenceCode)" title="是否必填">
                    <template slot-scope="text,record">
                      <ZgCheckbox @change="handlePropertyChange('isNeed',record.isNeed,record)" v-model="record.isNeed">必填</ZgCheckbox>
                    </template>
                  </a-table-column>
                  <a-table-column v-if="['all','base'].includes(currConfSenceCode)" title="排序字段">
                    <template slot-scope="text,record">
                      <ZgCheckbox v-if="record.columnType==='int'" @change="handlePropertyChange('isSort',record.isSort,record)" v-model="record.isSort">排序</ZgCheckbox>
                    </template>
                  </a-table-column>
                  <a-table-column v-if="['all','base'].includes(currConfSenceCode)" title="正则表达式" :width="360">
                    <template slot-scope="text,record">
                      <ZgInput @enter="handlePropertyChange('regex',record.regex,record)" v-model="record.regex"></ZgInput>
                    </template>
                  </a-table-column>
                  <a-table-column v-if="['all','base'].includes(currConfSenceCode)" title="错误提示语" :width="200">
                    <template slot-scope="text,record">
                      <ZgInput @enter="handlePropertyChange('errorMsg',record.errorMsg,record)" v-model="record.errorMsg"></ZgInput>
                    </template>
                  </a-table-column>
                  <a-table-column v-if="['all','base'].includes(currConfSenceCode)" title="模糊匹配">
                    <template slot-scope="text,record">
                      <a-switch @change="handlePropertyChange('likeShow',$event,record)" v-model="record.likeShow" checked-children="显示" un-checked-children="不显示"/>
                    </template>
                  </a-table-column>
                  <a-table-column v-if="['all','view'].includes(currConfSenceCode)" title="查询视图">
                    <template slot-scope="text,record">
                      <a-switch @change="handlePropertyChange('searchShow',$event,record)" v-model="record.searchShow" checked-children="显示" un-checked-children="不显示"/>
                    </template>
                  </a-table-column>
                  <a-table-column v-if="['all','view'].includes(currConfSenceCode)" title="新增视图">
                    <template slot-scope="text,record">
                      <a-switch @change="handlePropertyChange('addShow',$event,record)" v-model="record.addShow" checked-children="显示" un-checked-children="不显示"/>
                    </template>
                  </a-table-column>
                  <a-table-column v-if="['all','view'].includes(currConfSenceCode)" title="更新视图">
                    <template slot-scope="text,record">
                      <a-switch @change="handlePropertyChange('updateShow',$event,record)" v-model="record.updateShow" checked-children="显示" un-checked-children="不显示"/>
                    </template>
                  </a-table-column>
                  <a-table-column v-if="['all','view'].includes(currConfSenceCode)" title="批量更新视图">
                    <template slot-scope="text,record">
                      <a-switch @change="handlePropertyChange('batchShow',$event,record)" v-model="record.batchShow" checked-children="显示" un-checked-children="不显示"/>
                    </template>
                  </a-table-column>
                  <a-table-column v-if="['all','base'].includes(currConfSenceCode)" title="主表" :width="140">
                    <template slot-scope="text,record">
                      <span v-if="canSetFk(record)" >
                        <a-input placeholder="主表名" class="w120 mr10" v-model.trim="record.referTableName" @blur="handlePropertyChange('referTableName', record.referTableName, record)"></a-input>
                      </span>
                    </template>
                  </a-table-column>
                  <a-table-column title="操作" :width="80" fixed="right">
                    <template slot-scope="text,record">
                      <a-dropdown>
                        <a class="ant-dropdown-link mr10" @click="e => e.preventDefault()">
                          删除 <a-icon type="down" />
                        </a>
                        <a-menu slot="overlay">
                          <a-menu-item>
                            <a href="javascript:;" @click="delColConfig(record)" >仅删除配置</a>
                          </a-menu-item>
                          <a-menu-item>
                            <a href="javascript:;" @click="delColumn(record)" >删除配置和字段</a>
                          </a-menu-item>
                        </a-menu>
                      </a-dropdown>
                    </template>
                  </a-table-column>
                </a-table>
              </a-tab-pane>
              <a-tab-pane :key="2" tab="公共字段">
                <a-table
                  :customHeaderRow="customHeaderRow"
                  rowKey="name"
                  size="small"
                  bordered
                  :pagination="false"
                  :data-source="pubColumns">
                  <a-table-column title="名称" dataIndex="name"></a-table-column>
                  <a-table-column title="类型">
                    <template slot-scope="text,record">
                      <span>{{ record.type }}</span>
                      <span v-if="record.length>0">【{{ record.length }}】</span>
                    </template>
                  </a-table-column>
                  <a-table-column title="备注" dataIndex="comment"></a-table-column>
                </a-table>
              </a-tab-pane>
              <a-tab-pane :key="3" tab="模板管理">
                <Tmpl></Tmpl>
              </a-tab-pane>
              <a-tab-pane :key="4" tab="代码生成">
                <Generator :schema="schema" :table="currTable"></Generator>
              </a-tab-pane>
              <div slot="tabBarExtraContent">
                <a-dropdown v-if="tab===1">
                  <a class="ant-dropdown-link mr10" @click="e => e.preventDefault()">
                    {{ currConfName }} <a-icon type="down" />
                  </a>
                  <a-menu slot="overlay">
                    <a-menu-item @click="changeConfSence(conf)" v-for="(conf,i) in configArr" :key="`conf${i}`">
                      <a href="javascript:;">{{ conf.name }}</a>
                    </a-menu-item>
                  </a-menu>
                </a-dropdown>
                <a-tooltip v-if="tab===1">
                  <template slot="title">
                    补充当前配置中不存在的表字段
                  </template>
                  <a-button class="mr10" @click="initColumn" type="link">
                    <i class="fa fa-refresh mr5"></i>重载字段
                  </a-button>
                </a-tooltip>
                <a-button @click="addColumn" v-if="tab===1" type="link" >
                  <i class="fa fa-plus-circle mr5"></i>字段
                </a-button>
                <a-button @click="initPub" v-if="tab===2" type="link" >
                  <i class="fa fa-refresh mr5"></i>
                  <span v-if="pubColumns.length===0">初始化</span>
                  <span v-else>重置</span>
                </a-button>
              </div>
            </a-tabs>
          </div>
        </a-card>
      </a-col>
    </a-row>
  </div>
</template>
<script>
import TableEdit from './TableEdit'
import ColumnEdit from './ColumnEdit'
import OptionEdit from './OptionEdit'
import DicCodeSet from './DicCodeSet'
import Tmpl from './Tmpl'
import Generator from './Generator'
export default {
  components: {
    TableEdit, ColumnEdit, OptionEdit, DicCodeSet, Tmpl, Generator
  },
  data () {
    return {
      currConfSenceCode: 'base',
      configArr: [
        { name: '基础配置', code: 'base', scrollX: 1600, isCurr: true },
        { name: '视图配置', code: 'view', scrollX: 1200, isCurr: true },
        { name: '表头配置', code: 'header', scrollX: 800, isCurr: true },
        { name: '全部配置', code: 'all', scrollX: 3000, isCurr: true }
      ],
      tableLoading: false,
      showCrudModal: false,
      packageName: '',
      vueLocation: 'E:\\workspace\\vscode\\grid_web_new',
      tab: 1,
      codeTab: 1,
      loading: false,
      schema: 'base',
      prefix: '',
      parentTableName: '',
      total: 0,
      page: 0,
      pageSize: 8,
      tables: [],
      currTable: '',
      otherColumns: [],
      pubColumns: [],
      types: [
        { key: 'text', name: '单行文本', dataType: '字符串' },
        { key: 'textarea', name: '多行文本', dataType: '长文本' },
        { key: 'select', name: '下拉选择', dataType: '字符串' },
        { key: 'radio', name: '单选', dataType: '字符串' },
        { key: 'checkbox', name: '多选', dataType: '布尔值' },
        { key: 'int', name: '整数', dataType: '整数' },
        { key: 'double', name: '浮点数', dataType: '浮点数' },
        { key: 'switch', name: '开关', dataType: '布尔值' },
        { key: 'date', name: '日期', dataType: '日期' },
        { key: 'datetime', name: '日期时间', dataType: '日期时间' },
        { key: 'time', name: '时间', dataType: '时间' },
        { key: 'tags', name: '标签', dataType: '字符串' },
        { key: 'img', name: '单图', dataType: '字符串' },
        // { key: 'imgs', name: '多图', dataType: '字符串' },
        { key: 'attach', name: '附件', dataType: '字符串' },
        { key: 'tinymce', name: '富文本', dataType: '长文本' },
        { key: 'dic', name: '字典', dataType: '字符串' }
        // { key: 'user', name: '用户', dataType: '长整数' },
        // { key: 'depart', name: '部门', dataType: '长整数' },
        // { key: 'area', name: '地区', dataType: '字符串' }
      ]
    }
  },
  computed: {
    currConfName () {
      const arr = this.configArr.filter(t => {
        return t.isCurr
      })
      if (arr.length > 0) {
        return arr[0].name
      } else {
        return this.configArr[0].name
      }
    },
    scrollX () {
      const arr = this.configArr.filter(t => {
        return t.isCurr
      })
      if (arr.length > 0) {
        return arr[0].scrollX
      } else {
        return this.configArr[0].scrollX
      }
    },
    pageList () {
      const start = this.page < 0 ? 0 : this.page
      let end = start + this.pageSize
      end = end >= this.total ? this.total : end
      return this.tables.slice(start, end)
    }
  },
  mounted () {
    this.searchTable()
  },
  methods: {
    changeConfSence (conf) {
      this.configArr.filter(t => {
        return t.isCurr
      }).forEach(t => {
        t.isCurr = false
      })
      conf.isCurr = true
      this.currConfSenceCode = conf.code
    },
    customHeaderRow () {
      return {
        style: {
          background: '#f2f2f2'
        }
      }
    },
    initColumn () {
      this.confirm(() => {
        this.$http.post('/zg-generator/config/column/init', { schema: this.schema, tableName: this.currTable }, data => {
          this.otherColumns = data
        })
      }, '确定要重新设置表字段么')
    },
    handleMenuClick (e) {
      const key = e.key
      if (key === 1) {
        this.genEntity()
      } else if (key === 2) {
        this.genCrud()
      } else if (key === 3) {
        this.genTree()
      } else if (key === 4) {
        this.genChildCrud()
      }
    },
    canSetFk (col) {
      return col.columnType === 'bigint' && (col.columnName === 'pid' || col.columnName.endsWith('_id'))
    },
    handlePropertyChange (name, value, col) {
      this.$http.post('/zg-generator/config/column/property/set',
        {
          propertyName: name,
          propertyValue: value,
          tableName: col.tableName,
          columnName: col.columnName
        }, () => {
        })
    },
    findTypes (col) {
      return this.types.filter(t => {
        return t.dataType === col.dataType
      })
    },
    needOpts (col) {
      return col.compType === 'select' ||
        col.compType === 'multiple' ||
        col.compType === 'radio'
    },
    toSetOpts (col) {
      this.$refs.optEdit.show(col)
    },
    toSetDicCode (col) {
      this.$refs.dicCodeSet.show(col)
    },
    prev () {
      const page = this.page - this.pageSize
      this.page = page < 0 ? 0 : page
    },
    next () {
      const max = this.total
      const page = this.page + this.pageSize
      this.page = page >= max ? (max - 1) : page
    },
    searchTable () {
      this.tableLoading = true
      const handler = setTimeout(() => {
        this.tableLoading = false
      }, 60000)
      this.$http.get('/zg-generator/table/list', {
        schema: this.schema,
        prefix: this.prefix
      }, data => {
        clearTimeout(handler)
        this.tableLoading = false
        this.total = data.length
        this.tables = data
        if (data.length > 0) {
          this.change(data[0])
        }
      })
    },
    searchColumn () {
      const pubColNames = ['id', 'create_time', 'create_by', 'update_time', 'update_by', 'ver', 'is_del', 'search_str']
      this.$http.post('/zg-generator/config/column/list', { schema: this.schema, tableName: this.currTable }, data => {
        this.otherColumns = data
      })
      this.$http.get('/zg-generator/table/column/list', { schema: this.schema, tableName: this.currTable }, data => {
        this.pubColumns = data.filter(t => {
          return pubColNames.includes(t.name.toLowerCase())
        })
      })
    },
    change (table) {
      this.currTable = table
      // this.searchTable()
      this.searchColumn()
    },
    initPub () {
      const that = this
      that.$confirm({
        title: '重置会删除数据并重建字段，确定要重置' + that.schema + '.' + that.currTable + '的公共字段么?',
        onOk () {
          that.$http.post('/zg-generator/table/column/resetPub', {
            schema: that.schema,
            tableName: that.currTable
          }, () => {
            that.searchColumn()
          })
        }
      })
    },
    toAddTable () {
      this.$refs.tableEdit.show()
    },
    addTable (param) {
      const otherParam = JSON.parse(param)
      this.$http.post('/zg-generator/table/add',
        Object.assign({ schema: this.schema }, otherParam), () => {
          this.$refs.tableEdit.hide()
          this.change(otherParam.tableName)
          this.$info({ title: '操作成功' })
        })
    },
    delTable (table) {
      this.confirm(() => {
        this.$http.post('/zg-generator/table/del',
          { schema: this.schema, tableName: table }, () => {
            this.searchTable()
            this.$info({ title: '操作成功' })
          })
      })
    },
    addColumn () {
      this.$refs.columnEdit.show()
    },
    saveColumn (param) {
      this.$http.post('/zg-generator/table/column/merge',
        {
          schema: this.schema,
          tableName: this.currTable,
          columnVoList: JSON.parse(param)
        }, () => {
          this.$refs.columnEdit.hide()
          this.searchColumn()
          this.$info({ title: '操作成功' })
        })
    },
    delColConfig (col) {
      this.confirm(() => {
        this.$http.post('/zg-generator/config/column/del', {
          schema: this.schema,
          tableName: col.tableName,
          columnName: col.columnName
        }, () => {
          this.searchColumn()
        })
      })
    },
    delColumn (col) {
      this.confirm(() => {
        this.$http.post('/zg-generator/table/column/del', {
          schema: this.schema,
          tableName: col.tableName,
          columnName: col.columnName
        }, () => {
          this.searchColumn()
        })
      })
    },
    genEntity () {
      const that = this
      that.$confirm({
        title: '确定要为' + that.schema + '.' + that.currTable + '生成Entity代码么?',
        onOk () {
          that.$http.post('/zg-generator/code/entity/generate', {
            schema: that.schema,
            tableName: that.currTable
          }, data => {
            that.$info({ title: '操作成功！请到原代码处查看生成的代码' })
          })
        }
      })
    },
    genCrud () {
      this.showCrudModal = true
      /*
      const that = this
      that.$confirm({
        title: '确定要为' + that.schema + '.' + that.currTable + '生成CRUD代码么?',
        onOk () {
          that.$http.post('/zg-generator/code/crud/generator', { schema: that.schema, tableName: that.currTable }, data => {
            that.$info({ title: '操作成功！请到原代码处查看生成的代码' })
          })
        }
      }) */
    },
    doGenCrud () {
      if (this.packageName.length === 0) {
        this.$warning({ title: '请输入后台代码包名' })
        return
      }
      if (this.vueLocation.length === 0) {
        this.$warning({ title: '请输入前台代码位置' })
        return
      }

      this.$http.post('/zg-generator/code/crud/generate', {
        schema: this.schema,
        tableName: this.currTable,
        packageName: this.packageName,
        vueLocation: this.vueLocation
      }, () => {
        this.$info({ title: '操作成功！请到相关位置查看生成的代码' })
      })
    },
    genTree () {
      const that = this
      that.$confirm({
        title: '确定要为' + that.schema + '.' + that.currTable + '生成Tree代码么?',
        onOk () {
          that.$http.post('/zg-generator/code/tree/generate', { schema: that.schema, tableName: that.currTable }, data => {
            that.$info({ title: '操作成功！请到原代码处查看生成的代码' })
          })
        }
      })
    },
    genChildCrud () {
      const that = this
      if (this.parentTableName.length === 0) {
        this.$error({ title: '请设置主表名' })
        return
      }
      that.$confirm({
        title: '请确保已经为' + this.parentTableName + '生成了主表代码，确定要为' + that.schema + '.' + that.currTable + '生成字表CRUD代码么?',
        onOk () {
          that.$http.post('/zg-generator/code/child/generate', {
            schema: that.schema,
            tableName: that.currTable,
            parentTableName: that.parentTableName
          }, data => {
            that.$info({ title: '操作成功！请到原代码处查看生成的代码' })
          })
        }
      })
    }
  }
}
</script>
<style lang="less" scoped>
.ant-form-item{
  margin-bottom:10px;
}
.curr{
  background:#f2f2f2;
}
</style>
